import http from 'http'
import Koa from 'koa'
import koaBody from 'koa-body'

import {
  getIPv4IPAddress,
  colorconsole
} from './lib/utils'

const initServer = async (conf, moduler) => {
  try {
    const app = new Koa()

    app.use(koaBody({
      formLimit: '5mb',
      jsonLimit: '5mb',
      textLimit: '5mb'
    }))
    app.context.conf = conf

    for (let i = 0, len = moduler.moduleList.length; i < len; i++) {
      const moduleItem = moduler.moduleList[i]
      app.use(moduleItem.hash.applyRouter(app).routes())
    }

    const server = http.createServer(app.callback())
    app.server = server
    for (let i = 0, len = moduler.moduleList.length; i < len; i++) {
      const moduleItem = moduler.moduleList[i]
      if (typeof moduleItem.hash.beforeStart === 'function') {
        await moduleItem.hash.beforeStart(server, app)
      }
    }

    const { serverPort } = conf.defaults
    server.listen(serverPort, () => {
      const addr1 = `http://localhost:${serverPort}`
      const ip = getIPv4IPAddress()
      if (!ip) {
        colorconsole.warn(`### App Server ### 本机IP地址为空，无法通过WIFI调试`)
        return
      }
      const addr2 = `http://${ip}:${serverPort}`
      colorconsole.info(`### App Server ### 服务器地址: ${addr1}, ${addr2}`)
      colorconsole.info(`### App Server ### 请确保手机与App Server处于相同网段`)
    })

    app.on('error', (err, context) => {
      colorconsole.error(`### App Server ### 服务器错误: ${err.message}`)
      const errMsg = `出错了!HTTP error code: ${err.status}, 出错信息: ${err.message}`
      if (context) {
        context.body = errMsg
      }
    })

    server.on('error', (err) => {
      colorconsole.error(`### App Server ### 服务器错误: ${err.message}`)
      if (err.code === 'EADDRINUSE') {
        colorconsole.error(`### App Server ### 服务器错误:端口 ${serverPort} 被占用, 请检查`)
      }
    })

    process.on('SIGINT', () => {
      colorconsole.info(`### App Server ### SIGINT信号`)
      colorconsole.info(`### App Server ### 退出server进程 pid: ${process.pid}`)
      process.exit()
    })

    process.on('uncaughtException', (err) => {
      colorconsole.error(`### App Server ### 未定义的异常, 出错信息: ${err.message}`)
    })
  } catch (err) {
    colorconsole.error(`### App Server ### 服务器启动失败: ${err.message}`)
  }
}

const start = async (conf, moduler) => {
  initServer(conf, moduler)
}

export {
  start
}